package concurrent_util;

/**
 * @description:
 * @author: ywk
 * @date: 2020-12-05
 */


import java.util.Map;
import java.util.concurrent.*;


public class CyclicBarrierDemo implements Runnable {
    /**
     * 创建4个屏障,处理完之后,执行当前类的run方法
     */
    private CyclicBarrier cyclicBarrier = new CyclicBarrier(4, this);

    /**
     * 启动4个线程
     */
    private Executor executor = Executors.newFixedThreadPool(4);


    /**
     * 保存每个sheet计算出来的银行交易流水结果
     */
    private ConcurrentHashMap<String, Integer> sheetBankWaterCount = new ConcurrentHashMap<String, Integer>();


    /**
     * 交易流水统计
     */
    private void count() {
        for (int i = 0; i < 4; i++) {
            executor.execute(new Runnable() {
                public void run() {
                    // 模拟计算当前sheet的银行交易流水数据的业务处理
                    sheetBankWaterCount.put(Thread.currentThread().getName(), 1);
                    // 银行交易流水计算完成后,插入一个屏障
                    try {
                        cyclicBarrier.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        run();
    }


    /**
     * 汇总计算结果
     */

    public void run() {
        int result = 0;
        for (Map.Entry<String, Integer> sheet : sheetBankWaterCount.entrySet()) {
            result += sheet.getValue();
        }

        // 设置计算结果,并输出
        sheetBankWaterCount.put("result", result);
    }

    public static void main(String[] args) {
        CyclicBarrierDemo service = new CyclicBarrierDemo();
        service.count();
    }
    static class ThreadWithThread_2 extends Thread{
        private static int num = 5;
        private static CyclicBarrier cyclicBarrier = new CyclicBarrier(num);

        public void run() {
            try {

                System.out.println(Thread.currentThread().getName() + "等待全组线程准备完毕");
                cyclicBarrier.await();
                System.out.println(Thread.currentThread().getName() +  "等待完毕, 开始运行");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }

        }

        public static void main(String[] args) {
            for (int i=0; i< num; i++) {
                ThreadWithThread_2 threadWithThread = new ThreadWithThread_2();
                threadWithThread.start();
            }
        }
    }
}